package org.csu.mybigpro.aspect;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.binding.MapperMethod;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.csu.mybigpro.annotation.OperationLogAnnotation;
import org.csu.mybigpro.domain.OperationLog;
import org.csu.mybigpro.service.OperationLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Slf4j
@Aspect
@Component
public class OperationLogAspect {
    @Autowired
    private OperationLogService operationLogService;

    @Pointcut("@annotation(org.csu.mybigpro.annotation.OperationLogAnnotation)")
    public void logPointCut() {}

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = null;
        String status = "SUCCESS";
        String errorMsg = null;

        try {
            result = joinPoint.proceed();
            return result;
        } catch (Exception e) {
            status = "FAIL";
            errorMsg = e.getMessage();
            throw e;
        } finally {
            long duration = System.currentTimeMillis() - start;
            saveOperationLog(joinPoint, status, errorMsg);
        }
    }

    private void saveOperationLog(ProceedingJoinPoint joinPoint, String status, String errorMsg) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        OperationLogAnnotation annotation = method.getAnnotation(OperationLogAnnotation.class);

        OperationLog log = new OperationLog();
        log.setOperationModule(annotation.module());
        log.setOperationType(annotation.type());
        log.setOperationDesc(annotation.description());
        log.setMethod(method.getDeclaringClass().getName() + "." + method.getName());
        log.setParams(JSON.toJSONString(joinPoint.getArgs()));
        log.setIpAddress("127.0.0.1"); // 可用工具类获取真实IP
        log.setUsername("admin");      // 可从上下文中获取用户信息
        log.setStatus(status);
        log.setErrorMsg(errorMsg);
        log.setCreateTime(LocalDateTime.now());

        operationLogService.save(log);
    }
}
